<?php
namespace app\backend\service;
use app\backend\model\AdminModel;
use app\backend\model\MenuModel;
use app\common\RootService;
use app\backend\model\AuthModel;

class AuthService extends RootService
{
    /**
     * 权限列表
     * @return array
     * @throws \app\common\RootException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function authTree()
    {
        return infiniteRecursionMenus($this->myAuth());
    }

    /**
     * 操作权限
     * @param array $currentUri
     * @return array
     * @throws \app\common\RootException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function actionBtn(array $currentUri)
    {
        // 用户信息
        $authMenuIds = explode(',', adminInfo('authMenuIds'));
        // 操作按钮
        $where = ['app' => $currentUri[0], 'controller' => $currentUri[1], 'action' => $currentUri[2]];
        $action = MenuModel::where($where)->with('subMenu')->find();
        empty($action) || $action = $action->toArray();
        // 数据处理
        empty($action['subMenu']) || array_walk($action['subMenu'], function ($row) use (&$actionBtn, $authMenuIds) {
            // 普通管理员
            in_array($row['id'], $authMenuIds) && $actionBtn[$row['action']] = true;
            // 系统管理员
            in_array($authMenuIds[0], ['*']) && $actionBtn[$row['action']] = true;
        });
        return $actionBtn ?? [];
    }

    /**
     * 我的权限
     * @return array
     * @throws \app\common\RootException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function myAuth()
    {
        return $this->menuList($this->authModel(adminInfo('id'))->value('menu_ids'));
    }

    /**
     * 对选中的权限进行整合
     * @param array $selectMenuIds
     * @return array
     * @throws \app\common\RootException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function checkedAuth(array $selectMenuIds)
    {
        // 我的菜单列表
        $menuList = $this->myAuth();
        // 数据整合处理
        empty($menuList) || array_walk($menuList, function (&$row) use ($selectMenuIds) {
            // 选中菜单
            $row['checked'] = in_array($row['id'], $selectMenuIds) ? true : false;
            // 系统管理员全选所有菜单
            if (in_array($selectMenuIds[0], ['*']) && $row['state']) {
                $row['checked'] = true;
                $row['disabled'] = true;
            }
        });
        return infiniteRecursionMenus($menuList);
    }

    /**
     * 菜单列表
     * @param string $menuIds
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    protected function menuList(string $menuIds)
    {
        // 筛选启用的菜单
        $where = [['sm.is_show', '=', 1]];
        // 是否显示所有菜单
        in_array($menuIds, ['*']) || array_push($where, ['sm.id', 'in', explode(',', $menuIds)]);
        // 筛选字段
        $fields = ['sm.id', 'sm.title', 'sm.remark', 'pm.title as pTitle', 'sm.is_menu', 'sm.parent_id', 'sm.state'];
        // 返回
        $menuList = MenuModel::alias('sm')->join(['sys_menu' => 'pm'], 'sm.parent_id = pm.id', 'left')
            ->where($where)->field($fields)->select()->toArray();
        // 数据处理
        array_walk($menuList, function (&$row) {
            $row['value'] = $row['id'];
            $row['name'] = $row['title'];
            $row['disabled'] = $row['state'] ? false : true;
        });
        return $menuList;
    }

    /**
     * 角色模型
     * @param int $adminId
     * @return mixed
     */
    protected function authModel(int $adminId)
    {
        return AdminModel::alias('a')->join(['sys_role' => 'rol'], 'a.role_id = rol.id', 'left')->field(['rol.menu_ids'])
            ->where(['a.id' => $adminId]);
    }
}